<?php

abstract class Gtux_Model_Abstract
{
  /**
   * @var Gtux_Model_Gateway_Abstract
   */
  protected $_gateway;
  /**
   * logger
   *
   * @var Zend_Log_Writer_Abstract
   */
  protected $_logger;
  
  public function __construct(array $options = null, Zend_Db_Table_Row_Abstract $row = null) 
  {
    if (is_array($options)) 
    {
      $this->setOptions($options);
    }
    $this->_logger = Zend_Registry::get('logger');
    if (null !== $row) 
    {
      $this->setFromRow($row);
    }    
  }
  
  public function __set($name, $value) 
  {
    $method = 'set'.$name;
    if (('mapper' == $name) || !method_exists($this, $method)) 
    {
      $inflector = new Zend_Filter_Inflector(':field', array(':field' => array('Word_UnderscoreToCamelCase')));
      $name      = $inflector->filter(array('field' => $name));
      $method    = 'set'.$name;
      if (('mapper' == $name) || !method_exists($this, $method)) 
      {
        throw new BadMethodCallException('Bad setting method: '.$name);
      }
    }
    $this->$method($value);
  }
  
  public function __get($name) 
  {
    $method = 'get'.$name;
    if (('mapper' == $name) || !method_exists($this, $method)) 
    {
      $inflector = new Zend_Filter_Inflector(':field', array(':field' => array('Word_UnderscoreToCamelCase')));
      $name      = $inflector->filter(array('field' => $name));
      $method    = 'get'.$name;
      if (('mapper' == $name) || !method_exists($this, $method)) 
      {
        throw new BadMethodCallException('Bad getting method: '.$name);
      }
    }
    return $this->$method();
  }
  
  public function setOptions(array $options) 
  {
    $methods = get_class_methods($this);
    $filter = new Zend_Filter_Word_UnderscoreToCamelCase();
    
    foreach ($options as $key => $value) 
    {
      $method = 'set'.$filter->filter($key);
      
      if (in_array($method, $methods)) 
      {
        $this->$method($value);
      }     
    }
    return $this;
  }
  
  /**
   * @param Gtux_Model_Gateway_Abstract $gateway
   * @return Gtux_Model_Abstract
   */
  public function setGateway(Gtux_Model_Gateway_Abstract $gateway) 
  {
    $this->_gateway = $gateway;
    return $this;
  }

  /**
   * Return the mapper gateway for model
   *
   * @return Gtux_Model_Gateway_Abstract
   */
  abstract public function getGateway();
  
  /**
   * Graba los datos del modelo
   * 
   */
  public function save() 
  {
    return $this->getGateway()->save($this);
  }
  
  /**
   * Busca en la base de datos el registro de la variable
   *
   * @param int $id
   * @return Variable
   */
  public function find($id) 
  {
    $this->getGateway()->find($id, $this);
    return $this;
  }
  
  /**
   * Returns all te records
   *
   * @return array
   */
  public function fetchAll() 
  {
    return $this->getGateway()->fetchAll();
  }
  
  /**
   * Elimina el modelo
   */
  public function delete() 
  {
    return $this->getGateway()->delete($this);
  }

  /**
   * Set fields in object from a row
   *
   * @param Zend_Db_Table_Row_Abstract $row
   * @return Gtux_Model_Abstract
   */
  public function setFromRow(Zend_Db_Table_Row_Abstract $row) 
  {
    $rowArray = $row->toArray();
    foreach ($rowArray as $column => $value) 
    {
      $this->$column = $value;
    }
    return $this;
  }
  
}

?>